// state
//
// master: string  The master.
// master_view: <string, string>  The participant believed to be master by each participant.
// last_work_ids: <string, int>  The last work ID that was processed from each participant's work proposals.
// 'PARTICIPANT_ID'_proposed_work: [[int, string], ... ]  A list of [work_id, work] tuples, representing proposed work by the participant.
// 'PARTICIPANT_ID'_pending_work: [string, ... ]  A list of work that needs to be processed by a participant.
//
var MY_ID = null;
var MASTER = null;
var PARTICIPANT_LIST = null;
var MY_WORK_LIST = [];
var NEXT_WORK_ID = 0;
var evalWork = null;

function setEvalWorkCallback(fn) {
	evalWork = fn;
}

function writeToState(key, value) {
	gapi.hangout.data.setValue(key, value);
}

function maybeBecomeMaster(state) {
	if (state["master"] === "" || state["master"] === undefined) {
		writeToState("master", MY_ID);
	}
}

function updateMasterView(state) {
	var master_view = JSON.parse(state["master_view"]);
	if (state["master"] != master_view[MY_ID]) {
		master_view[MY_ID] = state["master"];
		writeToState("master_view", JSON.stringify(master_view));
	}
}

function iAmMaster(state) {
	if (MASTER != MY_ID) return false;
	var master_view = JSON.parse(state["master_view"]);
	for (var participant in PARTICIPANT_LIST) {
		if (master_view[participant.id] != MY_ID) {
			return false;
		}
	}
	return true;
}

function ProposeWork(work) {
	MY_WORK_LIST.append([NEXT_WORK_ID++, work]);
	writeToState(MY_ID + "_proposed_work", JSON.stringify(MY_WORK_LIST));
}

function MaybeBroadcastWork(state) {
	var last_work_ids = JSON.parse(state["last_work_ids"]);  // a map from participant ID to the last work ID processed
	for (var participant in PARTICIPANT_LIST) {
		var proposed_work = JSON.parse(state[participant + "_proposed_work"]);
		for (var work in proposed_work) {
			if (work[0] > last_work_ids) {
				last_work_ids[participant] = work[0];
				if (evalWork == null || evalWork(participant, work, state)) {
					for (var broadcast_participant in PARTICIPANT_LIST) {
						s
					}
				}
			}
		}
	}
	writeToState("last_work_ids", JSON.stringify(last_work_ids));
}

function DoPendingWork(state) {
	
}

function stateChanged(state, metadata) {
	MASTER = state["master"];
	maybeBecomeMaster(state);
	updateMasterView(state);
	if (iAmMaster(state)) {
		MaybeBroadcastWork();
	}
	DoPendingWork();
}

function participantsChanged(participants) {
	PARTICIPANT_LIST = gapi.hangout.getEnabledParticipants();
	if (gapi.hangout.getParticipantById(MASTER) == null) {
		writeToState("master", MY_ID);
	}
}

(function() {
  if (gapi && gapi.hangout) {
    var initHangout = function(apiInitEvent) {
      if (apiInitEvent.isApiReady) {
				MY_ID = gapi.hangout.getParticipantId();
        gapi.hangout.data.onStateChanged.add(function(stateChangeEvent) {
          stateChanged(stateChangeEvent.state,
                       stateChangeEvent.metadata);
        });
        gapi.hangout.onParticipantsChanged.add(function(partChangeEvent) {
          participantsChanged(partChangeEvent.participants);
        });
				stateChanged(gapi.hangout.data.getState(), gapi.hangout.data.getMetadata());
				maybeBecomeMaster(gapi.hangout.data.getState());
        gapi.hangout.onApiReady.remove(initHangout);
      }
    };

    gapi.hangout.onApiReady.add(initHangout);
  }
})();